﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Collections.ObjectModel;
using UBCon.Ribbon.Models;
using UBCon.Resources;
using UBCon.Ribbon.Interfaces;

namespace UBCon.Ribbon
{
    [StyleTypedProperty(Property = "ItemContainerStyle", StyleTargetType = typeof(RibbonGallery))]
    [TemplatePart(Name=FilterComboBoxName, Type=typeof(RibbonComboBox))]
    public class RibbonGallerySet:ItemsControl, IRibbonControl
    {
        #region Constructors

        static RibbonGallerySet() 
        {
            Type ownerType = typeof(RibbonGallerySet);
            RibbonGallerySet.DefaultStyleKeyProperty.OverrideMetadata(ownerType, new FrameworkPropertyMetadata(ownerType));
        }

        public RibbonGallerySet() : base() 
        {
            FilterItemsCollection = new ObservableCollection<FilterItemModel>();
        }

        #endregion

        #region Properties


        public bool IsFilterEnabled
        {
            get { return (bool)GetValue(IsFilterEnabledProperty); }
            set { SetValue(IsFilterEnabledProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsFilterEnabled.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsFilterEnabledProperty =
            DependencyProperty.Register("IsFilterEnabled", typeof(bool), typeof(RibbonGallerySet), 
            new PropertyMetadata(false));

        internal ObservableCollection<FilterItemModel> FilterItemsCollection
        {
            get { return (ObservableCollection<Models.FilterItemModel>)GetValue(FilterItemsCollectionProperty); }
            set { SetValue(FilterItemsCollectionProperty, value); }
        }

        // Using a DependencyProperty as the backing store for FilterItemsCollection.  This enables animation, styling, binding, etc...
        internal static readonly DependencyProperty FilterItemsCollectionProperty =
            DependencyProperty.Register("FilterItemsCollection", typeof(ObservableCollection<FilterItemModel>), typeof(RibbonGallerySet), new FrameworkPropertyMetadata(null));

        internal RibbonComboBox FilterComboBox 
        {
            get { return filterComboBox; }
            private set 
            {
                if (value != null && IsFilterEnabled)
                {
                    foreach (object item in Items)
                    {
                        if (item is RibbonGallery)
                        {
                            RibbonGallery gallery = item as RibbonGallery;
                            if (CanBeAdded(gallery))
                            {
                                FilterItemModel model = new FilterItemModel();
                                model.RibbonGallery = gallery;
                                model.Header = gallery.Header;
                                FilterItemsCollection.Add(model);
                            }
                        }
                    }
                    if (FilterItemsCollection.Count > 1)
                    {
                        FilterItemsCollection.Insert(0, new FilterItemModel() { Header = LocalizationResources.AllText, IsAll = true });
                    }
                    value.SelectedIndex = 0;
                }
                filterComboBox = value;
                
            }
        }

        #endregion

        #region Depenency Property Changed Callbacks

        private static void OnFilterablePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
        {
            RibbonGallerySet gallerySet = (RibbonGallerySet)sender;
            
        }

        static void gallerySet_Loaded(object sender, RoutedEventArgs e)
        {
            RibbonGallerySet gallerySet = (RibbonGallerySet)sender;
            gallerySet.Loaded -= gallerySet_Loaded;
            foreach (object item in gallerySet.Items)
            {
                if (item is RibbonGallery) 
                {
                    
                    RibbonGallery gallery = item as RibbonGallery;
                    if (gallerySet.CanBeAdded(gallery))
                    {
                        FilterItemModel model = new FilterItemModel();
                        model.RibbonGallery = gallery;
                        model.Header = gallery.Header;
                        gallerySet.FilterItemsCollection.Add(model);
                    }
                }
            }
            if (gallerySet.FilterItemsCollection.Count > 1)
            {
                gallerySet.FilterItemsCollection.Insert(0, new FilterItemModel() { Header = LocalizationResources.AllText, IsAll = true });
            }
            if (gallerySet.FilterComboBox != null) 
            {
                gallerySet.FilterComboBox.SelectedIndex = 0;
            }
        }

        private bool CanBeAdded(RibbonGallery gallery) 
        {
            return (from m in FilterItemsCollection where m.RibbonGallery == gallery select m).ToList().Count == 0;
        }

        internal void OnFilterItemSelected(FilterItemModel model) 
        {
            if (FilterItemsCollection.Contains(model)) 
            {
                List<FilterItemModel> items = (from m in FilterItemsCollection where m != model select m).ToList();

                if (model.IsAll)
                {
                    foreach (FilterItemModel item in items)
                    {
                        if (item.RibbonGallery != null) 
                        {
                            item.RibbonGallery.Visibility = System.Windows.Visibility.Visible;
                        }
                        if (item.IsSelected) item.IsSelected = false;
                    }
                }
                else 
                {
                    foreach (FilterItemModel item in items)
                    {
                        item.IsSelected = false;
                    }
                }
            }
        }
        #endregion

        #region Overrides

        /// <summary>
        /// Invoked whenever application code or internal processes (such as a rebuilding layout pass) call ApplyTemplate. 
        /// In simplest terms, this means the method is called just before a UI element displays in  app.  
        /// </summary>
        public override void OnApplyTemplate()
        {
            FilterComboBox = GetTemplateChild(FilterComboBoxName) as RibbonComboBox;

            if (FilterComboBox != null) 
            {
                FilterComboBox.IsFilterComboBox = true;
            }
            base.OnApplyTemplate();
        }

        /// <summary>
        ///Creates or identifies the element that is used to display the given item.
        /// </summary>
        /// <returns>Type: System.Windows.DependencyObject. The element that is used to display the given item.</returns>
        protected override DependencyObject GetContainerForItemOverride()
        {
            return new RibbonGallery();
        }

        /// <summary>
        /// Determines if the specified item is (or is eligible to be) its own ItemContainer. 
        /// (Overrides ItemsControl.IsItemItsOwnContainerOverride(Object).)
        /// </summary>
        /// <param name="item">Specified item.</param>
        /// <returns>true if the item is its own ItemContainer; otherwise, false.</returns>
        protected override bool IsItemItsOwnContainerOverride(object item)
        {
            return item is RibbonGallery;
        }
        #endregion

        #region Private Utilities
        #endregion

        #region Event Handlers
        #endregion

        #region Fields
        private const string FilterComboBoxName = "PART_FilterComboBox";
        private RibbonComboBox filterComboBox;
        #endregion

        #region Events
        #endregion

        #region IRibbonControl Implementation

        /// <summary>
        /// Gets a boolean value indicating whether the contol's size is large
        /// </summary>
        public bool IsLarge
        {
            get { return true; }
        }

        #endregion
    }
}
